home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CUCD / Programming / OUI / filesel.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  21.2 KB  |  806 lines

  1. // $Id: filesel.cc 1.3 1997/07/14 04:21:44 dlorre Exp dlorre $
  2. #include "filesel.h"
  3.  
  4. void listedevs(void);
  5. BOOL getfile(screen *, STRPTR , STRPTR , STRPTR , STRPTR );
  6. void initlist(void);
  7. void takefile(void);
  8. void freelist(void);
  9. void fileevents(void);
  10. void checkpath(void);
  11. void displayfiles(void);
  12. void devlist(void);
  13. void DoKeys(IntuiMessage *);
  14. void stripspaces(STRPTR );
  15. void bcpl2c(BSTR b, STRPTR d);
  16. BOOL getPath(STRPTR , STRPTR );
  17. void selection(WORD x, WORD y) ;
  18. void DrawIcon(STRPTR name, WORD place) ;
  19. void sinsert(List *list, Node *node) ;
  20.  
  21. struct fileEntry {
  22.     STRPTR  name ;
  23.     BYTE    type ;
  24.     fileEntry() : type(NULL), name(NULL) {}
  25. };
  26.  
  27. int fecmp(const void *a, const void *b)
  28. {
  29. fileEntry *fa = (fileEntry *)a ;
  30. fileEntry *fb = (fileEntry *)b ;
  31.  
  32.     if (fa->type == fb->type) {
  33.         return strcmpi(fa->name, fb->name) ;
  34.     }
  35.     else {
  36.         return fb->type - fa->type ;
  37.     }
  38. }
  39.  
  40. static fileEntry *fp ;
  41.  
  42. /* fichier control.c */
  43. LONG DeadKeyConvert(IntuiMessage *, UBYTE *, LONG, KeyMap *);
  44.  
  45. void filesel::fparent(gadget *g, unsigned long classe, unsigned short code)
  46. {
  47. STRPTR s;
  48.  
  49.     strcpy(stemp, DRAWER) ;
  50.     s = PathPart(stemp) ;
  51.     *s = '\0' ;
  52.     gdrawer->set(stemp) ;
  53.     DrawIcon(stemp, TOPDBOX) ;
  54.     freelist();
  55.     takefile();
  56. }
  57.  
  58. void filesel::fdrawer(gadget *g, unsigned long classe, unsigned short code)
  59. {
  60.     strcpy(stemp, DRAWER) ;
  61.     getPath(DRAWER, stemp);
  62.     checkpath();
  63.     gdrawer->set(stemp) ;
  64.     DrawIcon(stemp, TOPDBOX) ;
  65.     freelist();
  66.     takefile();
  67. }
  68.  
  69. void filesel::fprop(gadget *g, unsigned long classe, unsigned short code)
  70. {
  71.     if (code != topentry) {
  72.         topentry = code ;
  73.         displayfiles() ;
  74.     }
  75. }
  76.  
  77. void filesel::handlevkey(USHORT code)
  78. {
  79.     if (code == 0x0D) {
  80.         g->selectgadget(7, FALSE) ;
  81.     }
  82.     else if (code == 0x1B) {
  83.         g->selectgadget(9, FALSE) ;
  84.     }
  85.     else
  86.         g->parsegadgets(code) ;
  87. }
  88.  
  89. void filesel::open(screen *ns)
  90. {
  91. long mw ;
  92. long mc ;
  93. long l ;
  94. long pwidth, pheight ;
  95.  
  96.     ws = ns ;
  97.  
  98.     g = new gadgetlist(this, 10) ;
  99.     mw = g->lmax(ok, cancel, parent, NULL) + 20 ;
  100.     mc = g->lmax(file, drawer, comment, NULL) + 20 ;
  101.     l = g->fontheight+4 ;
  102.  
  103.     g->box(LEFTSEL, TOPSEL+HEIGHTSEL+4, mc, l) ;
  104.     new cstring(g, NULL, drawer, NULL, FALSE, PLACETEXT_IN|NG_HIGHLABEL) ;
  105.  
  106.     g->box(LEFTSEL+mc, TOPSEL+HEIGHTSEL+4, LEFTBOX + WIDTHBOX - mc - 20, l) ;
  107.     gdrawer = new string(g, WFUNC(&filesel::fdrawer)) ;
  108.  
  109.     g->box(LEFTSEL, TOPSEL+HEIGHTSEL+4+l, mc, l) ;
  110.     new cstring(g, NULL, file, NULL, FALSE, PLACETEXT_IN|NG_HIGHLABEL) ;
  111.  
  112.     g->box(LEFTSEL+mc, TOPSEL+HEIGHTSEL+4+l, LEFTBOX + WIDTHBOX - mc - 20, l) ;
  113.     gfile = new string(g, NULL, NULL, sname) ;
  114.  
  115.     g->box(LEFTSEL, TOPSEL+HEIGHTSEL+4+2*l, mc, l) ;
  116.     new cstring(g, NULL, comment, NULL, FALSE, PLACETEXT_IN|NG_HIGHLABEL) ;
  117.  
  118.     g->box(LEFTSEL+mc, TOPSEL+HEIGHTSEL+4+2*l, LEFTBOX + WIDTHBOX - mc - 20, l) ;
  119.     if (Saver)
  120.         gcom = new string(g, NULL) ;
  121.     else
  122.         cgcom = new cstring(g, NULL, NULL, NULL, TRUE) ;
  123.  
  124.     if (ws->scr->ViewPort.Modes & HIRES) {
  125.         pwidth = 18 ;
  126.         pheight = 10 ;
  127.     }
  128.     else {
  129.         pwidth = 13 ;
  130.         pheight = 11 ;
  131.     }
  132.  
  133.     g->box(pwidth-1, TOPSEL, pwidth-1, TOPSEL+pheight) ;
  134.     gprop = new eprop(g, WFUNC(&filesel::fprop), 0, TOT_DISPLAY, TOT_DISPLAY,
  135.         LORIENT_VERT, RIGHTPROP|HEIGHTPROP) ;
  136.  
  137.     g->box( ws->scr->WBorLeft+20,
  138.             g->maxh+8,
  139.             mw,
  140.             g->fontheight*3/2) ;
  141.  
  142.     g->setgpen(ws->xpens[GREEN_PEN]) ;
  143.     new fbutton(g, WFUNC(&filesel::fok), ok, TRUE) ;
  144.  
  145.     g->left = short((g->maxw+20-mw)/2) ;
  146.     g->setgpen(ws->drawinfo->dri_Pens[TEXTPEN]) ;
  147.     new fbutton(g, WFUNC(&filesel::fparent), parent, FALSE) ;
  148.  
  149.     g->left = short(g->maxw - mw) ;
  150.     g->setgpen(ws->xpens[RED_PEN]) ;
  151.     new fbutton(g, WFUNC(&filesel::fcancel), cancel, FALSE) ;
  152.  
  153.     width = short(LEFTBOX + WIDTHBOX+20) ;
  154.  
  155.     height = short(g->maxh-ws->winbarheight+8) ;
  156.  
  157.     left = short((ws->width - width - ws->scr->WBorLeft-ws->scr->WBorRight) / 2) ;
  158.     top = short((ws->height - height - ws->winbarheight - ws->scr->WBorBottom) / 2) ;
  159.  
  160.     window::_open(NULL, BUTTONIDCMP|ARROWIDCMP|SCROLLERIDCMP|
  161.                         IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_VANILLAKEY|
  162.                         IDCMP_DISKINSERTED|
  163.                         IDCMP_DISKREMOVED|IDCMP_IDCMPUPDATE,
  164.         WA_Flags,   WFLG_DRAGBAR|WFLG_ACTIVATE,
  165.         WA_Title,   title,
  166.         WA_Gadgets, g->glist,
  167.         WA_SizeGadget,  TRUE,
  168.         TAG_END);
  169.  
  170.     if (initok) {
  171.         recessedbox(LEFTSEL-2, TOPSEL-2, WIDTHSEL+4, HEIGHTSEL+4) ;
  172.         setapen(ws->xpens[GFILL_PEN]) ;
  173.         rectfill(LEFTSEL, TOPSEL, LEFTSEL+WIDTHSEL-1, TOPSEL+HEIGHTSEL-1) ;
  174.         bevelbox(LEFTBOX-2, TOPDBOX-2, WIDTHBOX+4, HEIGHTBOX+4) ;
  175.         recessedbox(LEFTBOX-2, TOPFBOX-2, WIDTHBOX+4, HEIGHTBOX+4) ;
  176.  
  177.         g->updategadgets() ;
  178.         if (newregion()) {
  179.             clipok = addregion(LEFTBOX, TOPDBOX, WIDTHBOX, HEIGHTBOX) ;
  180.             clipok &= addregion(LEFTBOX, TOPFBOX, WIDTHBOX, HEIGHTBOX) ;
  181.             clipok &= addregion(LEFTSEL, TOPSEL, WIDTHSEL, HEIGHTSEL) ;
  182.             if (!Saver)
  183.                 clipok &= addregion(LEFTSEL, TOPSEL+HEIGHTSEL+34, LEFTBOX+WIDTHBOX-LEFTSEL, 14) ;
  184.         }
  185.     }
  186. }
  187.  
  188. static filesel frwin(90, 40, 430, 140) ;
  189.  
  190. BOOL getfile(screen *s, STRPTR name, STRPTR title, STRPTR drawer,
  191.     STRPTR comment)
  192. {
  193. int i ;
  194.  
  195.     frwin.okflag = FALSE ;
  196.  
  197.     if (s == NULL) return(FALSE);
  198.     Plain = Italic = *s->scr->Font ;
  199.     Italic.ta_Style |= FSF_ITALIC;
  200.  
  201.     bloc = (FileInfoBlock *)AllocDosObject(DOS_FIB, NULL) ;
  202.     if (!bloc)
  203.         return FALSE ;
  204.  
  205.     ParsePatternNoCase("~(#?.info)", pat, MAXLEN) ;
  206.     Saver = short(comment != NULL) ;
  207.  
  208.     FONTHEIGHT = short(s->scr->Font->ta_YSize) ;
  209.     LEFTSEL = 20 ;
  210.     TOPSEL = TOPDBOX = short(s->winbarheight + 8) ;
  211.     WIDTHSEL = short(s->width / 3) ;
  212.     HEIGHTSEL = short(s->height / 2) ;
  213.     TOT_DISPLAY = short(HEIGHTSEL / FONTHEIGHT) ;
  214.     LEFTBOX = short(LEFTSEL + WIDTHSEL + 30) ;
  215.     TOPDBOX = TOPSEL ;
  216.     HEIGHTBOX = short(HEIGHTSEL / 2 - 10) ;
  217.     TOPFBOX = short(TOPSEL + HEIGHTBOX + 10) ;
  218.     WIDTHBOX = short((HEIGHTBOX*s->xratio) / s->yratio) ;
  219.  
  220.     listetext = new IntuiText[TOT_DISPLAY] ;
  221.     if (!listetext)
  222.         goto mem1 ;
  223.  
  224.     fpen = s->drawinfo->dri_Pens[TEXTPEN] ;
  225.     bpen = s->xpens[GFILL_PEN] ;
  226.  
  227.     for (i=0; i<TOT_DISPLAY; i++) {
  228.         listetext[i].FrontPen = fpen;
  229.         listetext[i].BackPen = bpen;
  230.         listetext[i].DrawMode = JAM2;
  231.         listetext[i].LeftEdge = short(LEFTSEL+4) ;
  232.         listetext[i].TopEdge = short(TOPSEL+i*FONTHEIGHT) ;
  233.         listetext[i].ITextFont = s->scr->Font ;
  234.         listetext[i].IText = new char[MAXLEN];
  235.         if (!listetext[i].IText)
  236.             goto mem2 ;
  237.  
  238.         listetext[i].IText[0] = '\0' ;
  239.         listetext[i].NextText = (i<(TOT_DISPLAY-1))?&listetext[i+1]:NULL;
  240.     }
  241.     Style = new TextAttr*[TOT_DISPLAY] ;
  242.     if (!Style)
  243.         goto mem3 ;
  244.  
  245.     strcpy(frwin.sname, name) ;
  246.     strcpy(frwin.title, title) ;
  247.     frwin.open(s) ;
  248.     if (frwin.initok) {
  249.         if (frwin.clipok) {
  250.             frwin.installclip() ;
  251.  
  252.             Mode = DISPLAY_FILES ;
  253.  
  254.             indsel = numsel = -1 ;
  255.  
  256.             getPath(drawer, stemp);
  257.             checkpath();
  258.             gdrawer->set(stemp) ;
  259.             DrawIcon(stemp, TOPDBOX) ;
  260.             DrawIcon(name, TOPFBOX) ;
  261.  
  262.             takefile();
  263.  
  264.             frwin.eventloop() ;
  265.  
  266.             frwin.disposeregion() ;
  267.  
  268.             freelist();
  269.             stripspaces(FILE);
  270.             strcpy(drawer, DRAWER) ;
  271.             strcpy(name, FILE) ;
  272.             if (Saver)
  273.                 strcpy(comment, COMMENT) ;
  274.         }
  275.  
  276.         frwin.close() ;
  277.     }
  278.     delete Style ;
  279.  
  280. mem3:
  281.     for (i=0; i<TOT_DISPLAY; i++) {
  282.         if (listetext[i].IText) delete listetext[i].IText ;
  283.     }
  284.  
  285. mem2:
  286.     delete listetext ;
  287.  
  288. mem1:
  289.     FreeDosObject(DOS_FIB, bloc) ;
  290.     return (frwin.okflag);
  291. }
  292.  
  293. void initlist(void)
  294. {
  295.     RepList = new List ;
  296.     NewList(RepList);
  297.     RepList->lh_Type = NT_UNKNOWN;
  298. }
  299.  
  300. void takefile(void)
  301. {
  302. ExAllData       *EAData ;
  303. ExAllData       *ead ;
  304. ExAllControl    *eac ;
  305. LONG            more ;
  306. int             i ;
  307.  
  308.     initlist();
  309.     checkpath();
  310.     clef = Lock(DRAWER, ACCESS_READ);
  311.  
  312.     EAData = new ExAllData[MAXENTRIES] ;
  313.  
  314.     eac = (ExAllControl *)AllocDosObject(DOS_EXALLCONTROL,NULL);
  315.  
  316.     nbfics = 0 ;
  317.     eac->eac_Entries = MAXENTRIES ;
  318.     eac->eac_MatchString = pat ;
  319.     eac->eac_MatchFunc = NULL ;
  320.     eac->eac_LastKey = 0;
  321.     do {
  322.         more = ExAll(clef, EAData, sizeof(ExAllData)*MAXENTRIES, ED_TYPE, eac);
  323.         if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES)) {
  324.             // ExAll failed abnormally
  325.             break;
  326.         }
  327.         if (eac->eac_Entries == 0) {
  328.             // ExAll failed normally with no entries
  329.             continue;                   // ("more" is *usually* zero)
  330.         }
  331.         ead = EAData;
  332.         do {
  333.             RepNode = new Node ;
  334.             RepNode->ln_Name = new char[strlen(ead->ed_Name)+1] ;
  335.             strcpy(RepNode->ln_Name, ead->ed_Name) ;
  336.             RepNode->ln_Pri = BYTE(ead->ed_Type > 0) ;
  337.             AddTail(RepList, RepNode) ;
  338.             nbfics++;
  339.             ead = ead->ed_Next;
  340.         } while (ead);
  341.  
  342.     } while (more);
  343.  
  344.     FreeDosObject(DOS_EXALLCONTROL,eac);
  345.     delete EAData ;
  346.  
  347.     fp = new fileEntry[nbfics] ;
  348.  
  349.     RepNode = RepList->lh_Head ;
  350.     for (i=0; i<nbfics; i++) {
  351.         fp[i].name = RepNode->ln_Name ;
  352.         fp[i].type = RepNode->ln_Pri ;
  353.         RepNode = RepNode->ln_Succ ;
  354.     }
  355.     qsort(fp, nbfics, sizeof(fileEntry), &fecmp) ;
  356.  
  357.     RepNode = RepList->lh_Head ;
  358.     for (i=0 ; i< nbfics; i++) {
  359.         RepNode->ln_Name = fp[i].name ;
  360.         RepNode->ln_Pri = fp[i].type ;
  361.         RepNode = RepNode->ln_Succ ;
  362.     }
  363.     delete [] fp ;
  364.  
  365.     UnLock(clef);
  366.     topentry = 0 ;
  367.     gprop->set(topentry, -1, nbfics) ;
  368.     displayfiles();
  369. }
  370.  
  371. void freelist(void)
  372. {
  373.     Garage = NULL;
  374.     for (RepNode = RepList->lh_Head; RepNode->ln_Succ;
  375.          RepNode = RepNode->ln_Succ) {
  376.  
  377.         if (Garage) {
  378.             Remove((Node *)Garage);
  379.             delete Garage ;
  380.         }
  381.  
  382.         delete RepNode->ln_Name ;
  383.  
  384.         Garage = RepNode;
  385.     }
  386.  
  387.     if (Garage) {
  388.         Remove((Node *)Garage);
  389.         delete Garage ;
  390.     }
  391.  
  392.     delete RepList ;
  393. }
  394.  
  395. void filesel::simpleevent(IntuiMessage *message)
  396. {
  397. Gadget *gad ;
  398. WORD mousex, mousey ;
  399. ULONG s, m ;
  400. TagItem *tags ;
  401. long id ;
  402.  
  403.     code = message->Code;
  404.     gad = (Gadget *)message->IAddress;
  405.     classe = message->Class;
  406.     mousex = message->MouseX ;
  407.     mousey = message->MouseY ;
  408.     s = message->Seconds ;
  409.     m = message->Micros ;
  410.  
  411.     clickon = FALSE ;
  412.  
  413.     switch (classe) {
  414.     case IDCMP_MOUSEBUTTONS:
  415.         if (code == SELECTUP) {
  416.             if (mousex > LEFTSEL && mousey > TOPSEL &&
  417.                 mousex < (LEFTSEL+WIDTHSEL) &&
  418.                 mousey < (TOPSEL+HEIGHTSEL)) {
  419.                 if (DoubleClick(declic.s, declic.m, s, m)) {
  420.                     clickon = TRUE ;
  421.                 }
  422.                 else {
  423.                     declic.s = s ;
  424.                     declic.m = m ;
  425.                 }
  426.             }
  427.             selection(mousex, mousey) ;
  428.         }
  429.         break;
  430.     case IDCMP_VANILLAKEY:
  431.         handlevkey(code) ;
  432.         break ;
  433.     case IDCMP_RAWKEY:
  434.         DoKeys(message);
  435.         break;
  436.     case IDCMP_DISKINSERTED:
  437.     case IDCMP_DISKREMOVED:
  438.         if (Mode == DISPLAY_DIRS) devlist() ;
  439.         break ;
  440.     case IDCMP_IDCMPUPDATE:
  441.         tags = (TagItem *)gad ;
  442.         if (FindTagItem(PGA_Top, tags)) {
  443.             code = (unsigned short)GetTagData(PGA_Top, 0, tags) ;
  444.             id = (unsigned short)GetTagData(GA_ID, 0, tags) ;
  445.             g->processgadget(id, classe, code) ;
  446.         }
  447.         break ;
  448.     case IDCMP_GADGETUP:
  449.     case IDCMP_GADGETDOWN:
  450.             g->processgadget(gad->GadgetID, classe, code) ;
  451.         break ;
  452.     case IDCMP_REFRESHWINDOW:
  453.         beginrefresh() ;
  454.         endrefresh(TRUE) ;
  455.         break;
  456.     }
  457. }
  458.  
  459. void checkpath(void)
  460. {
  461.     clef = NULL;
  462.     clef = Lock(stemp, ACCESS_READ);
  463.     if (!clef) {
  464.         strcpy(stemp, DRAWER) ;
  465.     }
  466.     else
  467.         UnLock(clef);
  468. }
  469.  
  470. void displayfiles(void)
  471. {
  472. int                 i ;
  473. long                l ;
  474. struct TextExtent   te ;
  475.  
  476.     RepNode = RepList->lh_Head;
  477.     i=0;
  478.     while (RepNode->ln_Succ && i++<topentry)
  479.         RepNode = RepNode->ln_Succ;
  480.  
  481.     i = 0;
  482.     while (RepNode->ln_Succ && (i<TOT_DISPLAY)) {
  483.         if (RepNode->ln_Pri)
  484.             Style[i] = &Italic ;
  485.         else
  486.             Style[i] = &Plain ;
  487.  
  488.         CopyMem(RepNode->ln_Name, listetext[i].IText, strlen(RepNode->ln_Name)+1);
  489.         l = (long)frwin.textfit(listetext[i].IText,
  490.                 strlen(listetext[i].IText), &te, NULL, 1,
  491.                  WIDTHSEL, FONTHEIGHT) ;
  492.         listetext[i].IText[l] = '\0' ;
  493.         i++ ;
  494.         RepNode = RepNode->ln_Succ;
  495.     }
  496.  
  497.     while (i<TOT_DISPLAY) {
  498.         listetext[i++].IText[0] = '\0' ;
  499.     }
  500.  
  501.     for (i=0 ; i<TOT_DISPLAY; i++) {
  502.         listetext[i].ITextFont = Style[i] ;
  503.         listetext[i].FrontPen =  (unsigned char)(((i+topentry) == numsel)?bpen:fpen) ;
  504.         listetext[i].BackPen =  (unsigned char)(((i+topentry) == numsel)?fpen:bpen) ;
  505.     }
  506.     frwin.setapen(frwin.ws->xpens[GFILL_PEN]) ;
  507.     frwin.rectfill(LEFTSEL, TOPSEL, LEFTSEL+WIDTHSEL-1, TOPSEL+HEIGHTSEL-1) ;
  508.     frwin.printitext(listetext, 0, 0) ;
  509. }
  510.  
  511. void devlist(void)
  512. {
  513. DosList *dol ;
  514.  
  515.     dol = LockDosList(LDF_VOLUMES|LDF_ASSIGNS|LDF_READ) ;
  516.     dol = NextDosEntry(dol, LDF_VOLUMES|LDF_ASSIGNS|LDF_READ) ;
  517.  
  518.     freelist();
  519.     initlist();
  520.     nbfics=0;
  521.     while (dol)
  522.     {
  523.         if ((dol->dol_Type != DLT_DEVICE) || dol->dol_Task) {
  524.             bcpl2c(dol->dol_Name, name);
  525.  
  526.             RepNode = new Node ;
  527.             RepNode->ln_Name = new char[strlen(name)+1] ;
  528.             strcpy(RepNode->ln_Name,name);
  529.             if (dol->dol_Type == DLT_DIRECTORY)
  530.                 RepNode->ln_Pri = 0;
  531.             else
  532.                 RepNode->ln_Pri = 1;
  533.             sinsert(RepList, RepNode) ;
  534.             nbfics++;
  535.         }
  536.         dol = NextDosEntry(dol, LDF_VOLUMES|LDF_ASSIGNS|LDF_READ) ;
  537.     }
  538.     UnLockDosList(LDF_VOLUMES|LDF_ASSIGNS|LDF_READ) ;
  539.     topentry = 0 ;
  540.     gprop->set(topentry, -1, nbfics) ;
  541.     displayfiles();
  542. }
  543.  
  544. void bcpl2c(BSTR b, STRPTR d)
  545. {
  546. STRPTR s = (STRPTR )BADDR(b);
  547. int i ;
  548.  
  549.     i = 0 ;
  550.     while (i<s[0])
  551.         d[i++] = s[i];
  552.     d[i++]=':'; d[i] = '\0';
  553. }
  554.  
  555.  
  556. BOOL getPath(STRPTR command, STRPTR buf)
  557. {
  558. BPTR lock;
  559. BOOL Success = FALSE;
  560.  
  561.     if (lock = Lock(command, ACCESS_READ)) {
  562.         Success = (short)NameFromLock(lock, buf, 64);
  563.         UnLock(lock);
  564.     }
  565.     return(Success);
  566. }
  567.  
  568. void stripspaces(STRPTR s)
  569. {
  570. int i,j;
  571. STATIC char cop[MAXLEN];
  572.     strcpy(cop, s);
  573.     i = j = 0;
  574.     while (cop[i] && cop[i] == ' ') i++ ;
  575.     while (cop[i]) s[j++] = cop[i++] ;
  576.     s[j] = '\0';
  577.     while (j && (s[j] == ' ' || s[j] == '\0'))
  578.         j-- ;
  579.     s[j+1] = '\0' ;
  580. }
  581.  
  582. void DoKeys(IntuiMessage *msg)
  583. {
  584. LONG numchars;
  585. UBYTE buffer[] = "           ";
  586.  
  587.     numchars = DeadKeyConvert(msg, buffer, 12, 0);
  588.     if (numchars)
  589.     {
  590.         switch (buffer[0]) {
  591.         case 0x9B:
  592.             switch (buffer[1]) {
  593.             case 'A':                   // DOWN ARROW
  594.                 topentry-- ;
  595.                 numsel-- ;
  596.                 if (numsel < 0) numsel = 0 ;
  597.                 if (topentry < 0) topentry = 0 ;
  598.                 break ;
  599.             case 'B':                   // UP ARROW
  600.                 topentry++ ;
  601.                 numsel++ ;
  602.                 if (numsel >= nbfics) numsel = short(nbfics-1) ;
  603.                 if (topentry >= nbfics) topentry = long(nbfics-1) ;
  604.                 break ;
  605.             }
  606.             gprop->set(topentry, -1, -1) ;
  607.             displayfiles() ;
  608.             break ;
  609.         case 0x1B:                  // ESC
  610.             frwin.active = FALSE;
  611.             break ;
  612.         case 0x0D:                  // RETURN
  613.             frwin.okflag = TRUE ; frwin.active = FALSE ;
  614.             break ;
  615.         case 0x08:
  616.         case '/':
  617.             frwin.fparent(NULL, 0, 0) ;
  618.             break ;
  619.         }
  620.     }
  621. }
  622.  
  623.  
  624. LONG DeadKeyConvert( IntuiMessage           *msg,
  625.                      UBYTE                  *kbuffer,
  626.                      LONG                   kbsize,
  627.                      KeyMap          *kmap)
  628. {
  629. STATIC InputEvent ievent = {NULL, IECLASS_RAWKEY, 0, 0, 0};
  630.  
  631.     if (msg->Class != IDCMP_RAWKEY)
  632.         return(-2);
  633.  
  634.     ievent.ie_Code = msg->Code;
  635.     ievent.ie_Qualifier = msg->Qualifier;
  636.     ievent.ie_position.ie_addr = *((APTR*)msg->IAddress);
  637.  
  638.     return(RawKeyConvert(&ievent, (STRPTR)kbuffer, kbsize, kmap));
  639. }
  640.  
  641. void listedevs(void)
  642. {
  643.     if (Mode == DISPLAY_FILES) {
  644.         indsel = numsel = -1 ;
  645.         frwin.removeclip() ;
  646.         frwin.recessedbox(LEFTBOX-2, TOPDBOX-2, WIDTHBOX+4, HEIGHTBOX+4) ;
  647.         frwin.bevelbox(LEFTBOX-2, TOPFBOX-2, WIDTHBOX+4, HEIGHTBOX+4) ;
  648.         frwin.installclip() ;
  649.         Mode = DISPLAY_DIRS;
  650.         devlist();
  651.     }
  652.     else {
  653.         indsel = numsel = -1 ;
  654.         frwin.removeclip() ;
  655.         frwin.bevelbox(LEFTBOX-2, TOPDBOX-2, WIDTHBOX+4, HEIGHTBOX+4) ;
  656.         frwin.recessedbox(LEFTBOX-2, TOPFBOX-2, WIDTHBOX+4, HEIGHTBOX+4) ;
  657.         frwin.installclip() ;
  658.         Mode = DISPLAY_FILES;
  659.         freelist();
  660.         takefile();
  661.     }
  662. }
  663.  
  664. void selection(WORD x, WORD y)
  665. {
  666. int ind, num ;
  667. int presel ;
  668.  
  669.     if (x > LEFTSEL && y > TOPSEL && x < (LEFTSEL+WIDTHSEL) && y < (TOPSEL+HEIGHTSEL)) {
  670.         ind = (y-TOPSEL) / FONTHEIGHT ;
  671.         num = int(ind + topentry) ;
  672.         if (num>=nbfics)
  673.             return ;
  674.         presel = indsel ;
  675.         indsel = short(ind) ;
  676.         numsel = short(num) ;
  677.         if ((Style[indsel] == &Italic) &&
  678.             (Mode == DISPLAY_FILES)) {  // Répertoire sélectionné
  679.             strcpy(DTEMP, DRAWER) ;
  680.             strcpy(stemp, DRAWER) ;
  681.             AddPart(stemp, listetext[indsel].IText, MAXLEN) ;
  682.             stripspaces(stemp) ;
  683.             checkpath();
  684.             gdrawer->set(stemp) ;
  685.             DrawIcon(stemp, TOPDBOX) ;
  686.             freelist();
  687.             takefile();
  688.         }
  689.         else if (Mode == DISPLAY_DIRS) {    // Volume ou Assign sélectionné
  690.             strcpy(stemp, listetext[indsel].IText) ;
  691.             stripspaces(stemp) ;
  692.             getPath(stemp, stemp);
  693.             checkpath();
  694.             gdrawer->set(stemp) ;
  695.             frwin.removeclip() ;
  696.             frwin.bevelbox(LEFTBOX-2, TOPDBOX-2, WIDTHBOX+4, HEIGHTBOX+4) ;
  697.             frwin.recessedbox(LEFTBOX-2, TOPFBOX-2, WIDTHBOX+4, HEIGHTBOX+4) ;
  698.             frwin.installclip() ;
  699.             DrawIcon(stemp, TOPDBOX) ;
  700.             Mode = DISPLAY_FILES;
  701.             freelist();
  702.             takefile();
  703.         }
  704.         else {  // Fichier sélectionné
  705.             if (clickon && presel == indsel) {
  706.                 frwin.okflag = TRUE ;
  707.                 frwin.active = FALSE ;
  708.                 return ;
  709.             }
  710.             strcpy(stemp2, listetext[indsel].IText) ;
  711.             stripspaces(stemp2) ;
  712.             gfile->set(stemp2) ;
  713.             strcpy(comstring, DRAWER) ;
  714.             AddPart(comstring, stemp2, MAXLEN) ;
  715.             clef = Lock(comstring, ACCESS_READ) ;
  716.             if (clef) {
  717.                 Examine(clef, bloc) ;
  718.                 strcpy(comstring, bloc->fib_Comment) ;
  719.                 UnLock(clef) ;
  720.             }
  721.             else
  722.                 comstring[0] = '\0' ;
  723.             if (Saver) {
  724.                 gcom->set(comstring) ;
  725.             }
  726.             else {
  727.                 cgcom->set(comstring) ;
  728.             }
  729.             DrawIcon(stemp2, TOPFBOX) ;
  730.         }
  731.         displayfiles() ;
  732.     }
  733.     else if (x > LEFTBOX && x < (LEFTBOX+WIDTHBOX)) {
  734.         if (y>TOPDBOX && y < (TOPDBOX+HEIGHTBOX) && Mode == DISPLAY_FILES) {
  735.             listedevs() ;
  736.         }
  737.         else if (y>TOPFBOX && y < (TOPFBOX+HEIGHTBOX) && Mode == DISPLAY_DIRS) {
  738.             listedevs() ;
  739.         }
  740.     }
  741. }
  742.  
  743. void DrawIcon(STRPTR name, WORD place)
  744. {
  745. DiskObject *diskobj;
  746. Image *im ;
  747. WORD w, h ;
  748. char fname[80] ;
  749. LONG deftype ;
  750.  
  751.     frwin.setapen(0) ;
  752.     frwin.rectfill(LEFTBOX, place, LEFTBOX+WIDTHBOX, place+HEIGHTBOX) ;
  753.     if (place == TOPDBOX) {
  754.         frwin.rectfill(LEFTBOX, TOPFBOX, LEFTBOX+WIDTHBOX, TOPFBOX+HEIGHTBOX) ;
  755.         strcpy(fname, name) ;
  756.         indsel = numsel = -1 ;
  757.         deftype = WBDRAWER ;
  758.     }
  759.     else {
  760.         if (name) {
  761.             strcpy(fname, DRAWER) ;
  762.             AddPart(fname, name, MAXLEN) ;
  763.         }
  764.         else {
  765.             fname[0] = '\0' ;
  766.         }
  767.         deftype = WBPROJECT ;
  768.     }
  769.     if ((diskobj=GetDiskObject((UBYTE *)fname)) || (diskobj=GetDefDiskObject(deftype))) {
  770.        im = (Image *)diskobj->do_Gadget.GadgetRender ;
  771.         w = short(MIN(WIDTHBOX, im->Width)) ;
  772.         h = short(MIN(HEIGHTBOX, im->Height)) ;
  773.         im->LeftEdge = short((WIDTHBOX-w) / 2) ;
  774.         im->TopEdge = short((HEIGHTBOX-h) / 2) ;
  775.         im->Depth = 2 ;
  776.         DrawImage(frwin.rp, im, LEFTBOX, place) ;
  777.         FreeDiskObject(diskobj);
  778.     }
  779. }
  780.  
  781.  
  782. void sinsert(List *list, Node *node)
  783. {
  784. Node *courant, *pred ;
  785.  
  786.     if (IsListEmpty(list)) {
  787.         AddHead(list, node) ;
  788.     }
  789.     else {
  790.         courant = list->lh_Head ;
  791.         if ((courant->ln_Pri < node->ln_Pri) ||
  792.             ((courant->ln_Pri == node->ln_Pri) &&
  793.             (stricmp(courant->ln_Name, node->ln_Name) > 0))) {
  794.             AddHead(list, node) ;
  795.         }
  796.         else {
  797.             while (courant->ln_Succ && ((courant->ln_Pri > node->ln_Pri) ||
  798.                 ((courant->ln_Pri == node->ln_Pri) && (stricmp(courant->ln_Name, node->ln_Name) < 0)))) {
  799.                 pred = courant ;
  800.                 courant = courant->ln_Succ ;
  801.             }
  802.             Insert(list, node, pred) ;
  803.         }
  804.     }
  805. }
  806.